package com.my.blog.website.utils;


import com.github.pagehelper.PageInfo;
import com.my.blog.website.config.CommonConfiguration;
import com.my.blog.website.constant.WebConst;
import com.my.blog.website.dto.Types;
import com.my.blog.website.modal.Vo.ContentVo;
import com.my.blog.website.modal.Vo.UserVo;
import com.vdurmont.emoji.EmojiParser;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.my.blog.website.constant.WebConst.initConfig;

/**
 * 主题公共函数
 * <p>
 * Created by 13 on 2017/2/21.
 */
@Component
public final class Commons {

    private static final Logger LOGGER = LoggerFactory.getLogger(Commons.class);

    public static String THEME = "themes/default";

    //默认除法运算精度
    private static final int DEF_DIV_SCALE = 2;

    @Resource
    private CommonConfiguration commonConfigurationAutowired;

    private static CommonConfiguration configuration;

    @PostConstruct
    public void init() {
        configuration = this.commonConfigurationAutowired;
    }

    /**
     * 判断分页中是否有数据
     *
     * @param paginator
     * @return
     */
    public static boolean is_empty(PageInfo paginator) {
        return paginator == null || (paginator.getList() == null) || (paginator.getList().size() == 0);
    }

    /**
     * 网站链接
     *
     * @return
     */
    public static String site_url() {
        return site_url("");
    }

    /**
     * 获取网站的blog名称
     * @version 2.0 2018-02-24
     *
     * @return
     */
    public static String webname(){
        String webName = WebConst.initConfig.get(WebConst.WEB_NAME);
        if(StringUtils.isBlank(webName)){
            //webName = getUploadBasePath(PropertiesUtils.getProperty(WebConst.WEB_NAME));

            webName = getUploadBasePath(configuration.getAppName());
            WebConst.initConfig.put(WebConst.WEB_NAME,webName);
        }
        return webName;
    }


    /**
     * 返回网站链接下的图片全址
     *
     * @param sub 后面追加的地址
     * @return
     *
     * @version 2.0 2018-03-24
     */
    public static String site_url(String sub, String type) {
        if(StringUtils.isBlank(type)){
            return site_url(sub);
        }
        if (Types.FILE_TYPE_IMAGE.getType().equals(type)){
            //return PropertiesUtils.getProperty(WebConst.UPLOAD_BASE_PATH) + File.separator + sub;
            return configuration.getBaseUploadPath() + File.separator + sub;
        }
        return site_option("site_url") + sub;
    }

    /**
     * 返回登录的用户
     *
     * @return
     *
     * @verison 2.0 2018-03-24
     */
    public static String loginName(HttpServletRequest request) {
        //return PropertiesUtils.getProperty(WebConst.WEB_URL);
        UserVo userVo = TaleUtils.getLoginUser(request);
        return userVo.getUsername();
    }

    /**
     * 是否拥有权限
     *
     * @return
     *
     * @verison 2.0 2018-03-24
     */
    public static boolean hasPemission(HttpServletRequest request) {
        return TaleUtils.isAdmin(request);
    }

    /**
     * 返回博客域名
     *
     * @return
     *
     * @verison 2.0 2018-03-24
     */
    public static String web_site() {
        //return PropertiesUtils.getProperty(WebConst.WEB_URL);
        return configuration.getWebDomain();
    }

    /**
     * 返回网站链接下的全址
     *
     * @param sub 后面追加的地址
     * @return
     */
    public static String site_url(String sub) {
        return site_option("site_url") + sub;
    }

    /**
     * 网站标题
     *
     * @return
     */
    public static String site_title() {
        return site_option("site_title");
    }

    /**
     * 网站配置项
     *
     * @param key
     * @return
     */
    public static String site_option(String key) {
        return site_option(key, "");
    }

    /**
     * 网站配置项
     *
     * @param key
     * @param defalutValue 默认值
     * @return
     */
    public static String site_option(String key, String defalutValue) {
        if (StringUtils.isBlank(key)) {
            return "";
        }
        String str = initConfig.get(key);
        if (StringUtils.isNotBlank(str)) {
            return str;
        } else {
            return defalutValue;
        }
    }

    /**
     * 截取字符串
     *
     * @param str
     * @param len
     * @return
     */
    public static String substr(String str, int len) {
        if (str.length() > len) {
            return str.substring(0, len);
        }
        return str;
    }

    /**
     * 返回主题URL
     *
     * @return
     */
    public static String theme_url() {
        return site_url(Commons.THEME);
    }

    /**
     * 返回主题下的文件路径
     *
     * @param sub
     * @return
     */
    public static String theme_url(String sub) {
        return site_url(Commons.THEME + sub);
    }

    /**
     * 返回github头像地址
     *
     * @param email
     * @return
     */
    public static String gravatar(String email) {
        String avatarUrl = "https://github.com/identicons/";
        if (StringUtils.isBlank(email)) {
            email = "user@hanshuai.xin";
        }
        String hash = TaleUtils.MD5encode(email.trim().toLowerCase());
        return avatarUrl + hash + ".png";
    }

    /**
     * 返回文章链接地址
     *
     * @param contents
     * @return
     */
    public static String permalink(ContentVo contents) {
        return permalink(contents.getCid(), contents.getSlug());
    }


    /**
     * 获取随机数
     *
     * @param max
     * @param str
     * @return
     */
    public static String random(int max, String str) {
        return UUID.random(1, max) + str;
    }

    /**
     * 返回文章链接地址
     *
     * @param cid
     * @param slug
     * @return
     */
    public static String permalink(Integer cid, String slug) {
        return site_url("/article/" + (StringUtils.isNotBlank(slug) ? slug : cid.toString()));
    }

    /**
     * 格式化unix时间戳为日期
     *
     * @param unixTime
     * @return
     */
    public static String fmtdate(Integer unixTime) {
        return fmtdate(unixTime, "yyyy-MM-dd");
    }

    /**
     * 格式化unix时间戳为日期
     *
     * @param unixTime
     * @param patten
     * @return
     */
    public static String fmtdate(Integer unixTime, String patten) {
        if (null != unixTime && StringUtils.isNotBlank(patten)) {
            return DateKit.formatDateByUnixTime(unixTime, patten);
        }
        return "";
    }

    /**
     * 显示分类
     *
     * @param categories
     * @return
     */
    public static String show_categories(String categories) throws UnsupportedEncodingException {
        if (StringUtils.isNotBlank(categories)) {
            String[] arr = categories.split(",");
            StringBuffer sbuf = new StringBuffer();
            for (String c : arr) {
                sbuf.append("<a href=\"/"+ webname() +"/category/" + URLEncoder.encode(c, "UTF-8") + "\">" + c + "</a>");
                //sbuf.append("<a href=\"/category/" + URLEncoder.encode(c, "UTF-8") + "\">" + c + "</a>");
            }
            return sbuf.toString();
        }
        return show_categories("默认分类");
    }

    /**
     * 显示标签
     *
     * @param tags
     * @return
     */
    public static String show_tags(String tags) throws UnsupportedEncodingException {
        if (StringUtils.isNotBlank(tags)) {
            String[] arr = tags.split(",");
            StringBuffer sbuf = new StringBuffer();
            for (String c : arr) {
                sbuf.append("<a href=\"/" + webname() + "/tag/" + URLEncoder.encode(c, "UTF-8") + "\">" + c + "</a>");
                //sbuf.append("<a href=\"/tag/" + URLEncoder.encode(c, "UTF-8") + "\">" + c + "</a>");
            }
            return sbuf.toString();
        }
        return "";
    }

    /**
     * 截取文章摘要
     *
     * @param value 文章内容
     * @param len   要截取文字的个数
     * @return
     */
    public static String intro(String value, int len) {
        int pos = value.indexOf("<!--more-->");
        if (pos != -1) {
            String html = value.substring(0, pos);
            return TaleUtils.htmlToText(TaleUtils.mdToHtml(html));
        } else {
            String text = TaleUtils.htmlToText(TaleUtils.mdToHtml(value));
            if (text.length() > len) {
                return text.substring(0, len);
            }
            return text;
        }
    }

    /**
     * 显示文章内容，转换markdown为html
     *
     * @param value
     * @return
     */
    public static String article(String value, HttpServletRequest request) {
        if (StringUtils.isNotBlank(value)) {
            value = value.replace("<!--more-->", "\r\n");
            String regex1 = "http://runblog.com/blog";
            String regex2 = "http://myblog.com/blog";
            if(value.contains(regex1) ||value.contains(regex2)){
                value = value.replace(regex1,WebConst.CONTEXT_PATH);
                value = value.replace(regex2,WebConst.CONTEXT_PATH);
            }
            value = value.replace(WebConst.CONTEXT_PATH, request.getContextPath());
            return TaleUtils.mdToHtml(value);
        }
        return "";
    }

    /**
     * 显示文章缩略图，顺序为：文章第一张图 -> 随机获取
     * 不推荐使用，图片消耗流量，首页加载太慢
     * TODO 有待优化
     *
     * @return
     */
    public static String show_thumb(ContentVo contents) {
        int cid = contents.getCid();
        int size = cid % 23;
        size = size == 0 ? 1 : size;
        return "/user/img/rand/" + size + ".jpg";
    }


    /**
     * An :grinning:awesome :smiley:string &#128516;with a few :wink:emojis!
     * <p>
     * 这种格式的字符转换为emoji表情
     *
     * @param value
     * @return
     */
    public static String emoji(String value) {
        return EmojiParser.parseToUnicode(value);
    }

    /**
     * 获取文章第一张图片
     *
     * @return
     */
    public static String show_thumb(String content) {
        content = TaleUtils.mdToHtml(content);
        if (content.contains("<img")) {
            String img = "";
            String regEx_img = "<img.*src\\s*=\\s*(.*?)[^>]*?>";
            Pattern p_image = Pattern.compile(regEx_img, Pattern.CASE_INSENSITIVE);
            Matcher m_image = p_image.matcher(content);
            if (m_image.find()) {
                img = img + "," + m_image.group();
                // //匹配src
                String reg = "src\\s*=\\s*\'?\"?(.*?)(\'|\"|>|\\s+)";
                Matcher m = Pattern.compile(reg).matcher(img);
                if (m.find()) {
                    return m.group(1);
                }
            }
        }
        return "";
    }

    private static final String[] ICONS = {"bg-ico-book", "bg-ico-game", "bg-ico-note", "bg-ico-chat", "bg-ico-code", "bg-ico-image", "bg-ico-web", "bg-ico-link", "bg-ico-design", "bg-ico-lock"};

    /**
     * 显示文章图标
     *
     * @param cid
     * @return
     */
    public static String show_icon(int cid) {
        return ICONS[cid % ICONS.length];
    }

    /**
     * 获取社交的链接地址
     *
     * @return
     */
    public static Map<String, String> social() {
        final String prefix = "social_";
        Map<String, String> map = new HashMap<>();
        map.put("weibo", initConfig.get(prefix + "weibo"));
        map.put("zhihu", initConfig.get(prefix + "zhihu"));
        map.put("github", initConfig.get(prefix + "github"));
        map.put("twitter", initConfig.get(prefix + "twitter"));
        return map;
    }

    /**
     * 获取上传文件根路径
     * @version 2.0 2018-03-24
     *
     * @return
     */
    public static String getUploadBasePath(){
        String basePath = WebConst.initConfig.get(WebConst.UPLOAD_BASE_PATH);
        if(StringUtils.isBlank(basePath)){
            //basePath = getUploadBasePath(PropertiesUtils.getProperty(WebConst.UPLOAD_BASE_PATH));

            basePath = configuration.getBaseUploadPath();
            WebConst.initConfig.put(WebConst.UPLOAD_BASE_PATH,basePath);
        }
        return basePath;
    }

    /**
     * 获取上传文件根路径
     *
     * @return
     */
    public static String getUploadBasePath(String uploadBasePath){
        // 校验文件上传路径的正确性
        if (StringUtils.isBlank(uploadBasePath) || "${upload.base.path}".equals(uploadBasePath)){
            String msg = "文件上传路径配置有错，请确认配置文件上传路径";
            LOGGER.error(msg);
            return null;
        }

        //去掉跟路径最后面的"/"
        if (uploadBasePath.endsWith("/")){
            uploadBasePath = uploadBasePath.substring(0,uploadBasePath.length());
        }

        return uploadBasePath;
    }

    /**
     * 获取上传文件根路径的类型
     *
     * @param uploadBasePath
     * @return
     */
    public static boolean isDefaultType(String uploadBasePath){
        return StringUtils.isBlank(uploadBasePath) || "${upload.base.path}".equals(uploadBasePath);
    }

    /**
     * 返回网站链接下的图片全址
     *
     * @param id 后面追加的图片id
     * @return
    */
    public static String site_image_url(Long id) {
        return "/static/upload/" + id;
    }

    /**
     * 获取上传文件的字节流
     *
     * @param fileUrl
     * @return
     * @throws Exception
     */
    public static byte[] getUploadFile(String fileUrl) throws Exception {
        byte[] data = null;
        if(StringUtils.isBlank(fileUrl) || !new File(fileUrl).exists()){
            return data;
        }

        FileInputStream input = null;
        ByteArrayOutputStream output = null;
        try {
            input = new FileInputStream(new File(fileUrl));
            output = new ByteArrayOutputStream();
            byte[] buf = new byte[1024];
            int numBytesRead = 0;
            while ((numBytesRead = input.read(buf)) != -1) {
                output.write(buf, 0, numBytesRead);
            }
            data = output.toByteArray();
        } catch (IOException e) {
            data = null;
        } finally {
            if (input != null){
                try {
                    input.close();
                } catch (IOException e) {
                    input = null;
                }
            }
            if (output != null){
                try {
                    output.close();
                } catch (IOException e) {
                    output = null;
                }
            }
        }

        return data;
    }

    /**
     * 还原上传文件的连接
     *
     * @param oldUrl
     * @param request
     * @return
     */
    public static String recoveryFileUrl(String oldUrl, HttpServletRequest request){
        LOGGER.debug("old={}",oldUrl);
        LOGGER.debug("contextPath={}",request.getContextPath());

        if (StringUtils.isNotBlank(oldUrl) && oldUrl.contains(WebConst.CONTEXT_PATH)){
            oldUrl = oldUrl.replace(WebConst.CONTEXT_PATH,request.getContextPath());
            String recoveryUrl = request.getServerName() + oldUrl;
            return recoveryUrl;
        }
        return oldUrl;
    }

    /**
     * 还原上传文件markdowncode的连接
     *
     * @param mdCode
     * @param request
     * @return
     */
    public static String recoveryFileUrlForMd(String mdCode, HttpServletRequest request){
        LOGGER.debug("mdCode={}",mdCode);
        LOGGER.debug("contextPath={}",request.getContextPath());

        /*if (StringUtils.isNotBlank(mdCode) && mdCode.contains(WebConst.CONTEXT_PATH)){
            //mdCode = mdCode.replace(WebConst.CONTEXT_PATH, "http://" +  request.getServerName() + request.getContextPath());
            mdCode = mdCode.replace(WebConst.CONTEXT_PATH, request.getContextPath());
            //String recoveryUrl = request.getServerName() + mdCode;
        }*/
        return mdCode;
    }

    /**
     * 自动适配文件大小,精度有问题，废弃
     *
     * @param fileSize
     * @return
     */
   /* public static String autoFileSize(Long fileSize){
        Long kbSize = 1024L;
        Long mbSize = 1024 * kbSize;
        Long gbSize = 1024 * mbSize ;

        try{
            if(fileSize < kbSize){
                return fileSize/kbSize + "KB";
            }else if (fileSize > kbSize && fileSize < mbSize){
                return fileSize/kbSize + "KB";
            }else if (fileSize > mbSize && fileSize < gbSize){
                BigDecimal b1 = new BigDecimal(Double.parseDouble(Long.toString(fileSize)));
                BigDecimal b2 = new BigDecimal(Double.parseDouble(Long.toString(mbSize)));
                *//**
                 * 第二个参数：表示小数位后精度
                 * 第三个参数：表示保留模式，直接删除多余小数位
                 *//*
                Double result  = b1.divide(b2,DEF_DIV_SCALE,BigDecimal.ROUND_DOWN).doubleValue();

                return  result.toString() + "MB";
            }
        } catch (Exception e){
            LOGGER.info("转换异常={}",e);
        }

        return "未知大小";
    }*/

    /**
     * 自动适配文件大小 v2 by 2018-01-14
     *
     * @param fileSize
     * @return
     */
    public static String autoFileSize(Long fileSize){
        try {
            Double originalSize = fileSize.doubleValue();
            double kByte = originalSize/1024;
            if (kByte < 1){
                return originalSize.toString()+"Bytes(s)";
            }

            double mbByte = kByte/1024;
            if(mbByte < 1){
                BigDecimal decimal1 = new BigDecimal(Double.toString(kByte));
                return decimal1.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString() + "KB";
            }

            double gbByte = mbByte/1024;
            if (gbByte < 1){
                BigDecimal decimal2 = new BigDecimal(Double.toString(mbByte));
                return decimal2.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString() + "MB";
            }

            double tbByte = gbByte/1024;
            if (tbByte < 1){
                BigDecimal decimal3 = new BigDecimal(Double.toString(gbByte));
                return  decimal3.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString() + "GB";
            }

            BigDecimal decimal4 = new BigDecimal(Double.toString(tbByte));
            return decimal4.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString() + "TB";
        }catch (Exception e){
            LOGGER.info("转换异常={}",e);
        }
        return "未知大小";
    }
}
